﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using CommonBase;
using MCDomain.DataAccess;
using MCDomain.Model;
using MContracts.Classes;
using UIShared.Commands;
using MContracts.Controls.Dialogs;
using MContracts.Dialogs;
using MContracts.Properties;
using MContracts.ViewModel.Helpers;
using McReports.ViewModel;
using MediatorLib;
using McReports.ViewModel;
using UIShared.ViewModel;
using UIShared.Common;
using McUIBased.Commands;
using McUIBase.ViewModel;
using McUIBase.Factories;

namespace MContracts.ViewModel
{
    /// <summary>
    /// The ViewModel for the application's main window.
    /// </summary>
    public partial class MainWindowViewModel : ViewModelBase
    {
        /// <summary>
        /// Получает единственный экземпляр модели представления главного окна
        /// </summary>
        public readonly static MainWindowViewModel Instance = new MainWindowViewModel();

        /// <summary>
        /// Получает объект команды закрытия
        /// </summary>
        public readonly Closable Closable;

        #region Constructor

        public MainWindowViewModel()
        {
            ViewMediator.Register(this);
            Closable = new Closable(this);
            Settings.Default.PropertyChanged += Default_PropertyChanged;
            InitializeProperties();
            ProceedStartupRequests();
        }

        private void ProceedStartupRequests()
        {
            if (ProjectStartupInfo.UpdateStatistics)
                using (var repository = RepositoryFactory.CreateContractRepository())
                {
                    
                    repository.With(x => x.TryGetContext()).Do(x => x.UpdateFundsStatistics());
                    repository.SubmitChanges();
                    
                }
        }

        public override string DisplayName
        {
            get { return string.Format("{0} {1} - [Cборка {2}]", ProductInfo, FileVersionInfo, AssemblyVersionInfo); }
            protected set { base.DisplayName = value; }
        }

        private void InitializeProperties()
        {
            DateTime now = DateTime.Today;


        }

        [MediatorMessageSink(RequestRepository.REQUEST_SELECTEDCONTRACT_CHANGED, ParameterType = typeof (bool))]
        public void SelectedContractChanged(bool flag)
        {
            OnPropertyChanged(() => SelectedContract);
        }

        private void Default_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            ViewMediator.NotifyColleagues(RequestRepository.REQUEST_GLOBAL_PROPERTIES_CHANGED, e);
        }

        #endregion // Constructor

        #region Commands

        private readonly NewContractdocParams _newGeneralParams = new NewContractdocParams(null,
                                                                                           NewContractdocType.NewGeneral);

        //private RelayCommand _createActReport_7_Command;
        //private RelayCommand _createContractQuarterPlanReport_4_Command;
        //private RelayCommand _createContractRegisterReport_2_Command;
        //private RelayCommand _createContractYearPlanReport_1_Command;
        //private RelayCommand _createContractsPeriodReport_3_Command;
        //private RelayCommand _createEfficientInformationReport_7_Command;
        private RelayCommand _createExcelContractQuarterPlanReport_4_Command;
        private RelayCommand _createExcelContractsPeriodReport_3_Command;
        private RelayCommand _createExcelEfficientInformationReport_7_1_Command;
        //private RelayCommand _createExcelEfficientInformationReport_7_Command;
        private RelayCommand _createExcelHandingWorkReport_6_Command;
        private RelayCommand _createExcelSubContractReport_5_Command;
        private RelayCommand _createExcelYearPlanReport1Command;
        //private RelayCommand _createHandingWorkReport_6_Command;
        private RelayCommand _createInformationReport_2_Command;
        //private RelayCommand _createSubContractReport_5_Command;
        private RelayCommand _createTransferActsContractsReport_8_1_Command;
        private RelayCommand _createTransferContractsReport_8_2_Command;
        //private RelayCommand _createWorkPlanQuarterReport_6_Command;
        private RelayCommand _deleteorcancelContractCommand;
        private RelayCommand _newAgreementCommand;
        private RelayCommand _newContractCommand;
        private RelayCommand _newSubgeneralCommand;
        private RelayCommand _openContractActsCommand;
        private RelayCommand _openContractCommand;
        private RelayCommand _openContractScheduleCommand;
        private RelayCommand _openToolsCommand;
        private RelayCommand _saveActiveWorkspaceCommand;
        //private DateTime _selectedFilterEndDate;
        //private DateTime _selectedFilterStartDate;
        private RelayCommand _showActRepositoryCommand;

        private RelayCommand _showContractRepositoryCommand;
        private RelayCommand _showDisposalsRepositoryCommand;
        private RelayCommand _showOrdersRepositoryCommand;
        private RelayCommand acttypesShowCommand;
        private RelayCommand approvalGoalsShowCommand;
        private RelayCommand approvalStatesShowCommand;
        private RelayCommand authoritiesShowCommand;
        private RelayCommand contractStatesShowCommand;
        private RelayCommand contractTypesShowCommand;
        private RelayCommand contractorpositionShowCommand;
        private RelayCommand contractorsShowCommand;
        private RelayCommand contractortypesShowCommand;
        private RelayCommand currenciesShowCommand;
        private RelayCommand currencymeasuresShowCommand;
        private RelayCommand degreesShowCommand;
        private RelayCommand departmentsShowCommand;
        private RelayCommand documentsShowCommand;
        private RelayCommand economefficiencyparametersShowCommand;
        private RelayCommand economefficiencytypesShowCommand;
        private RelayCommand efficienceparameterTypesShowCommand;
        private RelayCommand employeesShowCommand;
        private RelayCommand funccustomerpersonsShowCommand;
        private RelayCommand functionalcustomersShowCommand;
        private RelayCommand functionalcustomertypesShowCommand;
        private RelayCommand locationsShowCommand;
        private RelayCommand missiveTypesShowCommand;
        private AutoSubmitCommand multiEditActsCommand;
        private RelayCommand ndsalgorithmesShowCommand;
        private RelayCommand ndsesShowCommand;
        private RelayCommand ntpsubviewsShowCommand;
        private RelayCommand ntpviewsShowCommand;
        private RelayCommand personsShowCommand;
        private RelayCommand positionsShowCommand;
        private RelayCommand prepaymentdocumenttypesShowCommand;
        private RelayCommand propertiesShowCommand;
        private RelayCommand regionsShowCommand;
        private RelayCommand rolesShowCommand;
        private RelayCommand saveLogFileCommand;
        private RelayCommand sightfuncpersonschemesShowCommand;
        private RelayCommand transferacttypedocumentsShowCommand;
        private RelayCommand transferacttypesShowCommand;
        private RelayCommand troublesShowCommand;
        private RelayCommand troublesregistresShowCommand;
        private RelayCommand worktypesShowCommand;
        private RelayCommand сontractorpropertiesShowCommand;
        private RelayCommand yearreportcolorsShowCommand;

        public ICommand LogonCommand
        {
            get { return new RelayCommand((param) => Logon()); }
        }

        public RelayCommand ShowContractRepositoryCommand
        {
            get
            {
                return _showContractRepositoryCommand ??
                       (_showContractRepositoryCommand = new RelayCommand(param => ShowContractRepository()));
            }
        }


        public Filterstate _selectedfilterstate;
        public Filterstate SelectedFilterstate
        {
            get { return _selectedfilterstate; }
            set
            {
                _selectedfilterstate = value;
                OnPropertyChanged(()=>SelectedFilterstate);
                OnPropertyChanged(()=>SelectedFilterStartDate);
                OnPropertyChanged(()=>SelectedFilterEndDate);
            }
        }
    
        public DateTime SelectedFilterStartDate
        {
            get { return SelectedFilterstate.Return(x => x.Startdate, DateTimeExtensions.StartOfTheYear(DateTime.Now.Year)); }
        }

        public DateTime SelectedFilterEndDate
        {
            get { return SelectedFilterstate.Return(x => x.Finishdate, DateTimeExtensions.EndOfTheYear(DateTime.Now.Year)); }
        }

        public RelayCommand ShowActRepositoryCommand
        {
            get
            {
                return _showActRepositoryCommand ??
                       (_showActRepositoryCommand = new RelayCommand(param => ShowActRepository()));
            }
        }

        public RelayCommand OpenContractActsCommand
        {
            get
            {
                return _openContractActsCommand ??
                       (_openContractActsCommand =
                        new RelayCommand(param => OpenContractActs(), x=>CanOpenContractDetails()));
            }
        }

        private bool CanOpenContractDetails()
        {
            var ws = ActiveWorkspace as IContractdocRefHolder;
            return ws != null && ws.ContractdocId.HasValue;
        }

        public RelayCommand ShowDisposalsRepositoryCommand
        {
            get
            {
                return _showDisposalsRepositoryCommand ??
                       (_showDisposalsRepositoryCommand = new RelayCommand(param => ShowDisposalsRepository()));
            }
        }

        public RelayCommand ShowOrdersRepositoryCommand
        {
            get
            {
                return _showOrdersRepositoryCommand ??
                       (_showOrdersRepositoryCommand = new RelayCommand(param => ShowOrdersRepository()));
            }
        }


        public RelayCommand ContractTypesShowCommand
        {
            get
            {
                return contractTypesShowCommand ??
                       (contractTypesShowCommand =
                        new RelayCommand(param => ContractTypesShow(), x => CanContractTypesShow));
            }
        }

        public RelayCommand ContractorpropertiesShowCommand
        {
            get
            {
                return сontractorpropertiesShowCommand ??
                       (сontractorpropertiesShowCommand = new RelayCommand(param => ContractorpropertiesShow(),
                                                                           x => CanContractorpropertiesShow));
            }
        }

        public RelayCommand SightfuncpersonschemesShowCommand
        {
            get
            {
                return sightfuncpersonschemesShowCommand ??
                       (sightfuncpersonschemesShowCommand = new RelayCommand(param => SightfuncpersonschemesShow(),
                                                                             x => CanSightfuncpersonschemesShow));
            }
        }


        public RelayCommand YearTemplanCommand
        {
            get
            {
                return _createExcelYearPlanReport1Command ??
                       (_createExcelYearPlanReport1Command =
                        new RelayCommand(p => CreateExcelYearPlanReport_1(),
                                         (x) => ActiveWorkspace is ContractRepositoryViewBasedViewModel&&SelectedFilterstate.IsYear));
            }
        }



        public RelayCommand CreateInformationReportCommand
        {
            get
            {
                return _createInformationReport_2_Command ??
                       (_createInformationReport_2_Command =
                        new RelayCommand(p => CreateExcelInformationReport_2(),
                                         (x) => ActiveWorkspace is ContractRepositoryViewBasedViewModel&&SelectedFilterstate.IsYear));
            }
        }


        

        public RelayCommand CreateExcelContractsPeriodReportCommand
        {
            get
            {
                return _createExcelContractsPeriodReport_3_Command ??
                       (_createExcelContractsPeriodReport_3_Command =
                        new RelayCommand(p => CreateExcelContractsPeriodReport_3(),
                                         (x) => ActiveWorkspace is ContractRepositoryViewBasedViewModel&&SelectedFilterstate.IsYear));
            }
        }



        public RelayCommand OpenContractScheduleCommand
        {
            get
            {
                return _openContractScheduleCommand ??
                       (_openContractScheduleCommand =
                        new RelayCommand(p => OpenContractSchedule(), (x) => CanOpenContractDetails()));
            }
        }

        public RelayCommand QuarterTemplanCommand
        {
            get
            {
                return _createExcelContractQuarterPlanReport_4_Command ??
                       (_createExcelContractQuarterPlanReport_4_Command =
                        new RelayCommand(p => CreateExcelContractQuarterPlanReport_4(),
                                         (x) => ActiveWorkspace is ContractRepositoryViewBasedViewModel&&SelectedFilterstate.IsQuarter));
            }
        }

        public RelayCommand CreateExcelSubContractReportCommand
        {
            get
            {
                return _createExcelSubContractReport_5_Command ??
                       (_createExcelSubContractReport_5_Command =
                        new RelayCommand(p => CreateExcelSubContractReport_5(),
                                         (x) => ActiveWorkspace is ContractRepositoryViewBasedViewModel));
            }
        }



        public RelayCommand CreateExcelHandingWorkReportCommand
        {
            get
            {
                return _createExcelHandingWorkReport_6_Command ??
                       (_createExcelHandingWorkReport_6_Command =
                        new RelayCommand(p => CreateExcelHandingWorkReport_6(),
                                         (x) => ActiveWorkspace is ContractRepositoryViewBasedViewModel));
            }
        }



        public RelayCommand CreateMonthExcelEfficientInformationReportCommand
        {
            get
            {
                return _createExcelEfficientInformationReport_7_1_Command ??
                       (_createExcelEfficientInformationReport_7_1_Command =
                        new RelayCommand(p => CreateExcelEfficientInformationReport_7_1(),
                                         (x) => ActiveWorkspace is ContractRepositoryViewBasedViewModel));
            }
        }



        public ICommand ExportRegistryToExcel
        {
            get { return new RelayCommand(x => ExportRegistry()); }
        }

        public RelayCommand CreateTransferActsContractsReport_8_1_Command
        {
            get
            {
                return _createTransferActsContractsReport_8_1_Command ??
                       (_createTransferActsContractsReport_8_1_Command =
                        new RelayCommand(p => CreateTransferActsContractsReport_8_1(),
                                         (x) =>
                                         ((ActiveWorkspace is ContractViewModel) &&
                                          (ActiveWorkspace as ContractViewModel).Contractdoc != null)));
            }
        }

        public RelayCommand CreateTransferContractsReport_8_2_Command
        {
            get
            {
                return _createTransferContractsReport_8_2_Command ??
                       (_createTransferContractsReport_8_2_Command =
                        new RelayCommand(p => CreateTransferContractsReport_8_2(),
                                         (x) => ((ActiveWorkspace is ContractViewModel) &&
                                                 (ActiveWorkspace as ContractViewModel).Contractdoc != null)));
            }
        }

        public RelayCommand OpenToolsCommand
        {
            get { return _openToolsCommand ?? (_openToolsCommand = new RelayCommand(p => OpenToolsDialog())); }
        }

        public ICommand DeleteOrCancelContractCommand
        {
            get
            {
                return _deleteorcancelContractCommand ?? (_deleteorcancelContractCommand = new RelayCommand(
                                                                                               x => SendDeleteContract(),
                                                                                               x => ContractSelected));
            }
        }

        private bool ActsSelected
        {
            get
            {
                if (ActiveWorkspace is ActRepositoryViewModel)
                    return (ActiveWorkspace as ActRepositoryViewModel).SelectedActs.Count > 1;

                return false;
            }
        }

        public AutoSubmitCommand MultiEditActsCommand
        {
            get
            {
                return multiEditActsCommand ??
                       (multiEditActsCommand = new AutoSubmitCommand(x => MultiEdit(), x => ActsSelected,
                                                                     RepositoryFactory.CreateContractRepository()));
            }
        }

        public RelayCommand FunccustomerpersonsShowCommand
        {
            get
            {
                return funccustomerpersonsShowCommand ??
                       (funccustomerpersonsShowCommand = new RelayCommand(param => FunccustomerpersonsShow(),
                                                                          x => CanFunccustomerpersonsShow));
            }
        }


        public RelayCommand DocumentsShowCommand
        {
            get
            {
                return documentsShowCommand ??
                       (documentsShowCommand = new RelayCommand(param => DocumentsShow(), x => CanDocumentsShow));
            }
        }

        public RelayCommand TransferacttypesShowCommand
        {
            get
            {
                return transferacttypesShowCommand ??
                       (transferacttypesShowCommand = new RelayCommand(param => TransferacttypesShow(),
                                                                       x => CanTransferacttypesShow));
            }
        }

        public RelayCommand TransferacttypedocumentsShowCommand
        {
            get
            {
                return transferacttypedocumentsShowCommand ??
                       (transferacttypedocumentsShowCommand = new RelayCommand(param => TransferacttypedocumentsShow(),
                                                                               x => CanTransferacttypedocumentsShow));
            }
        }

        public RelayCommand FunctionalcustomersShowCommand
        {
            get
            {
                return functionalcustomersShowCommand ??
                       (functionalcustomersShowCommand = new RelayCommand(param => FunctionalcustomersShow(),
                                                                          x => CanFunctionalcustomersShow));
            }
        }

        public RelayCommand FunctionalcustomertypesShowCommand
        {
            get
            {
                return functionalcustomertypesShowCommand ??
                       (functionalcustomertypesShowCommand = new RelayCommand(param => FunctionalcustomertypesShow(),
                                                                              x => CanFunctionalcustomertypesShow));
            }
        }

        public RelayCommand PersonsShowCommand
        {
            get
            {
                return personsShowCommand ??
                       (personsShowCommand = new RelayCommand(param => PersonsShow(), x => CanPersonsShow));
            }
        }

        public RelayCommand EmployeesShowCommand
        {
            get
            {
                return employeesShowCommand ??
                       (employeesShowCommand = new RelayCommand(param => EmployeesShow(), x => CanEmployeesShow));
            }
        }

        public RelayCommand DepartmentsShowCommand
        {
            get
            {
                return departmentsShowCommand ??
                       (departmentsShowCommand = new RelayCommand(param => DepartmentsShow(), x => CanDepartmentsShow));
            }
        }

        public RelayCommand RegionsShowCommand
        {
            get
            {
                return regionsShowCommand ??
                       (regionsShowCommand = new RelayCommand(param => RegionsShow(), x => CanRegionsShow));
            }
        }

        public RelayCommand ActtypesShowCommand
        {
            get
            {
                return acttypesShowCommand ??
                       (acttypesShowCommand = new RelayCommand(param => ActtypesShow(), x => CanActtypesShow));
            }
        }

        public RelayCommand NtpviewsShowCommand
        {
            get
            {
                return ntpviewsShowCommand ??
                       (ntpviewsShowCommand = new RelayCommand(param => NtpviewsShow(), x => CanNtpviewsShow));
            }
        }

        public RelayCommand YearreportcolorsShowCommand
        {
            get
            {
                return yearreportcolorsShowCommand ??
                       (yearreportcolorsShowCommand =
                        new RelayCommand(param => YearreportcolorsShow(), x => CanYearreportcolorsShow));
            }
        }

        public RelayCommand LocationsShowCommand
        {
            get
            {
                return locationsShowCommand ??
                       (locationsShowCommand = new RelayCommand(param => LocationsShow(), x => CanTroublesregistresShow));
            }
        }

        public RelayCommand MissiveTypesShowCommand
        {
            get
            {
                return missiveTypesShowCommand ??
                       (missiveTypesShowCommand = new RelayCommand(param => MissiveTypesShow(),
                                                                   x => CanTroublesregistresShow));
            }
        }


        public RelayCommand ApprovalGoalsShowCommand
        {
            get
            {
                return approvalGoalsShowCommand ??
                       (approvalGoalsShowCommand = new RelayCommand(param => ApprovalGoalsShow(),
                                                                    x => CanTroublesregistresShow));
            }
        }

        public RelayCommand ApprovalStatesShowCommand
        {
            get
            {
                return approvalStatesShowCommand ??
                       (approvalStatesShowCommand = new RelayCommand(param => ApprovalStatesShow(),
                                                                     x => CanTroublesregistresShow));
            }
        }


        public RelayCommand TroublesregistresShowCommand
        {
            get
            {
                return troublesregistresShowCommand ??
                       (troublesregistresShowCommand = new RelayCommand(param => TroublesregistresShow(),
                                                                        x => CanTroublesregistresShow));
            }
        }

        public RelayCommand ContractortypesShowCommand
        {
            get
            {
                return contractortypesShowCommand ??
                       (contractortypesShowCommand = new RelayCommand(param => ContractortypesShow(),
                                                                      x => CanContractortypesShow));
            }
        }

        public RelayCommand ContractorsShowCommand
        {
            get
            {
                return contractorsShowCommand ??
                       (contractorsShowCommand = new RelayCommand(param => ContractorsShow(), x => CanContractorsShow));
            }
        }

        public RelayCommand NtpsubviewsShowCommand
        {
            get
            {
                return ntpsubviewsShowCommand ??
                       (ntpsubviewsShowCommand = new RelayCommand(param => NtpsubviewsShow(), x => CanNtpsubviewsShow));
            }
        }

        public RelayCommand CurrenciesShowCommand
        {
            get
            {
                return currenciesShowCommand ??
                       (currenciesShowCommand = new RelayCommand(param => CurrenciesShow(), x => CanCurrenciesShow));
            }
        }

        public RelayCommand ContractStatesShowCommand
        {
            get
            {
                return contractStatesShowCommand ??
                       (contractStatesShowCommand = new RelayCommand(param => ContractStatesShow(),
                                                                     x => CanContractStatesShow));
            }
        }

        public RelayCommand NdsesShowCommand
        {
            get
            {
                return ndsesShowCommand ??
                       (ndsesShowCommand = new RelayCommand(param => NdsesShow(), x => CanNdsesShow));
            }
        }

        public RelayCommand NdsalgorithmesShowCommand
        {
            get
            {
                return ndsalgorithmesShowCommand ??
                       (ndsalgorithmesShowCommand =
                        new RelayCommand(param => NdsalgorithmsShow(), x => CanNdsalgorithmsShow));
            }
        }

        public RelayCommand PropertiesShowCommand
        {
            get
            {
                return propertiesShowCommand ??
                       (propertiesShowCommand = new RelayCommand(param => PropertiesShow(), x => CanPropertiesShow));
            }
        }

        public RelayCommand RolesShowCommand
        {
            get
            {
                return rolesShowCommand ??
                       (rolesShowCommand = new RelayCommand(param => RolesShow(), x => CanRolesShow));
            }
        }

        public RelayCommand PrepaymentdocumenttypesShowCommand
        {
            get
            {
                return prepaymentdocumenttypesShowCommand ??
                       (prepaymentdocumenttypesShowCommand = new RelayCommand(param => PrepaymentdocumenttypesShow(),
                                                                              x => CanPrepaymentdocumenttypesShow));
            }
        }

        public RelayCommand PositionsShowCommand
        {
            get
            {
                return positionsShowCommand ??
                       (positionsShowCommand = new RelayCommand(param => PositionsShow(), x => CanPositionsShow));
            }
        }

        public RelayCommand WorktypesShowCommand
        {
            get
            {
                return worktypesShowCommand ??
                       (worktypesShowCommand = new RelayCommand(param => WorktypesShow(), x => CanWorktypesShow));
            }
        }

        public RelayCommand SaveLogFileCommand
        {
            get { return saveLogFileCommand ?? (saveLogFileCommand = new RelayCommand(param => SaveLogFile(), x => true)); }
        }

        public RelayCommand EconomefficiencytypesShowCommand
        {
            get
            {
                return economefficiencytypesShowCommand ??
                       (economefficiencytypesShowCommand = new RelayCommand(param => EconomefficiencytypesShow(),
                                                                            x => CanEconomefficiencytypesShow));
            }
        }

        public RelayCommand EfficienceparameterTypesShowCommand
        {
            get
            {
                return efficienceparameterTypesShowCommand ??
                       (efficienceparameterTypesShowCommand = new RelayCommand(param => EfficienceparameterTypesShow(),
                                                                               x => CanEfficienceparameterTypesShow));
            }
        }

        public RelayCommand EconomefficiencyparametersShowCommand
        {
            get
            {
                return economefficiencyparametersShowCommand ??
                       (economefficiencyparametersShowCommand =
                        new RelayCommand(param => EconomefficiencyparametersShow(),
                                         x => CanEconomefficiencyparametersShow));
            }
        }

        public RelayCommand DegreesShowCommand
        {
            get
            {
                return degreesShowCommand ??
                       (degreesShowCommand = new RelayCommand(param => DegreesShow(), x => CanDegreesShow));
            }
        }

        public RelayCommand TroublesShowCommand
        {
            get
            {
                return troublesShowCommand ??
                       (troublesShowCommand = new RelayCommand(param => TroublesShow(), x => CanTroublesShow));
            }
        }

        public RelayCommand CurrencymeasuresShowCommand
        {
            get
            {
                return currencymeasuresShowCommand ??
                       (currencymeasuresShowCommand = new RelayCommand(param => CurrencymeasuresShow(),
                                                                       x => CanCurrencymeasuresShow));
            }
        }

        public RelayCommand ContractorpositionsShowCommand
        {
            get
            {
                return contractorpositionShowCommand ??
                       (contractorpositionShowCommand = new RelayCommand(param => ContractorpositionShow(),
                                                                         x => CanContractorpositionShow));
            }
        }

        public RelayCommand AuthoritiesShowCommand
        {
            get
            {
                return authoritiesShowCommand ??
                       (authoritiesShowCommand = new RelayCommand(param => AuthoritiesShow(), x => CanAuthoritiesShow));
            }
        }

        public RelayCommand NewContractCommand
        {
            get
            {
                return _newContractCommand ??
                       (_newContractCommand = new RelayCommand(param => NewContract(_newGeneralParams)));
            }
        }

        public RelayCommand NewAgreementCommand
        {
            get { return CreateNewContractCommand(NewContractdocType.NewAgreement, ref _newAgreementCommand); }
        }


        public RelayCommand NewSubgeneralCommand
        {
            get { return CreateNewContractCommand(NewContractdocType.NewSubgeneral, ref _newSubgeneralCommand); }
        }

        private ContractRepositoryViewBasedViewModel CurrentContractRepositoryViewModel
        {
            get { return (ActiveWorkspace as ContractRepositoryViewBasedViewModel); }
        }

        public Contractdoc SelectedContract
        {
            get { return CurrentContractRepositoryViewModel == null ? null : CurrentContractRepositoryViewModel.Current; }
        }

        private bool ContractSelected
        {
            get
            {
                return (CurrentContractRepositoryViewModel != null) &&
                       (CurrentContractRepositoryViewModel.CurrentContractRepositoryView != null);
            }
        }

        public RelayCommand OpenContractCommand
        {
            get
            {
                return _openContractCommand ??
                       (_openContractCommand = new RelayCommand(param => OpenContract(SelectedContract),
                                                                x => ContractSelected));
            }
        }

        public RelayCommand SaveActiveWorkspaceCommand
        {
            get
            {
                return _saveActiveWorkspaceCommand ??
                       (_saveActiveWorkspaceCommand = new RelayCommand(x => SaveActiveWorkspace(),
                                                                       x => CanSaveActiveWorkspace()));
            }
        }

        /// <summary>
        /// Событие запроса сохранения рабочей области перед проведением следующей операции
        /// Аргумент принимает значение Истина, если пользователь согласился на сохранение рабочей области и будет выполнять
        /// следующую операцию. Ложь - при отказе от продолжения
        /// </summary>
        public event EventHandler<EventParameterArgs<bool>> RequestSaveModifiedWorkspace;

        public void OnRequestSaveModifiedWorkspace(EventParameterArgs<bool> e)
        {
            EventHandler<EventParameterArgs<bool>> handler = RequestSaveModifiedWorkspace;
            if (handler != null) handler(this, e);
        }

        private void OpenContractSchedule()
        {
            OpenContractWorkspace<ScheduleViewModel>();
        }

        private bool RequestAndSaveWorkspace(WorkspaceViewModel ws)
        {
            Contract.Requires(ws != null);
            if (!ws.IsModified) return true;
            var args = new EventParameterArgs<bool>(false);
            OnRequestSaveModifiedWorkspace(args);
            if (!args.Parameter) return false;
            SaveActiveWorkspace();
            return true;
        }

        private void OpenContractWorkspace<TWorkspace>() where TWorkspace : ContractWorkspaceViewModel
        {
            var contractdocHolder = ActiveWorkspace as IContractdocRefHolder;
            Contract.Assert(contractdocHolder != null);
            var oid = contractdocHolder.ContractdocId;
            Contract.Assert(oid.HasValue);
            var ws = FindContractWorkspace<TWorkspace>(oid.Value);
            if (ws == null)
            {
                if (!RequestAndSaveWorkspace(ActiveWorkspace)) return;
                // Повторное получение идентификатора договора после сохранения.
                // Требуется, если объект был зарегестрирован на вставку и не имел первичного ключа
                oid = contractdocHolder.ContractdocId;
                IContractRepository repository = RepositoryFactory.CreateContractRepository();
                ws = (TWorkspace) Activator.CreateInstance(typeof (TWorkspace), repository);
                ws.ContractObject = repository.GetContractdoc(oid.Value);
                AddWorkspace(ws);
            }
            SetActiveWorkspace(ws);
        }

        private void OpenContractActs()
        {
            OpenContractWorkspace<ActsViewModel>();
        }

        private T FindContractWorkspace<T>(long contractdocId) where T : ContractWorkspaceViewModel
        {
            return Workspaces.OfType<T>().SingleOrDefault(x => x.ContractObject.Id == contractdocId);
        }

        private void ExportRegistry()
        {
            CurrentContractRepositoryViewModel.ExportRegistry();
        }

        protected override void OnDispose()
        {
            MultiEditActsCommand.Dispose();
            base.OnDispose();
        }

        private void Logon()
        {
            var dlg = new ServerConnectionDialog();
            dlg.ShowDialog();
        }

        public event EventHandler<DeleteContractArgs> RequestDeleteContract;

        private void SendDeleteContract()
        {
            Contract.Requires(SelectedContract != null);
            bool canceled = false;
            if (RequestDeleteContract != null)
            {
                var args = new DeleteContractArgs(SelectedContract);
                RequestDeleteContract(this, args);
                canceled = args.Cancel;
            }

            if (canceled) return;

            if (ActiveWorkspace is ContractRepositoryViewBasedViewModel)
                ActiveWorkspace.CastTo<ContractRepositoryViewBasedViewModel>().DeleteContract(SelectedContract);


            OnPropertyChanged(() => SelectedContract);
        }

        private void MultiEdit()
        {
            Contract.Assert(MultiEditActsCommand.Repository.TryGetContext() != null);
            if (ActiveWorkspace is ActRepositoryViewModel)
                (ActiveWorkspace as ActRepositoryViewModel).MultiEdit();
        }


        private void OpenToolsDialog()
        {
            var dlg = new PropertyDialog {PropertyObject = new PropertiesDecorator()};
            if (dlg.ShowDialog().GetValueOrDefault())
            {
                Settings.Default.Save();
            }
            else
            {
                Settings.Default.Reload();
            }
        }

        private RelayCommand CreateNewContractCommand(NewContractdocType newContractdocType, ref RelayCommand instance)
        {
            return instance ?? (instance = new RelayCommand(
                                               param =>
                                               NewContract(new NewContractdocParams(SelectedContract,
                                                                                    newContractdocType)),
                                               x => ContractSelected));
        }


        private bool CanSaveActiveWorkspace()
        {
            return (ActiveWorkspace != null) && (ActiveWorkspace.SaveCommand.CanExecute(null));
        }

      

        #endregion // Commands

        #region Properties

        public WorkspaceViewModel ActiveWorkspace
        {
            get { return Workspaces.SingleOrDefault(x => x.IsActive); }
        }

        public bool RepositoryShowed
        {
            set
            {
                if (value)
                {
                    ShowContractRepository();
                }
            }
        }

        #endregion

        #region Workspaces

        /// <summary>
        /// Returns the collection of available workspaces to display.
        /// A 'workspace' is a ViewModel that can request to be closed.
        /// </summary>
        public ObservableCollection<WorkspaceViewModel> Workspaces
        {
            get
            {
                if (_workspaces == null)
                {
                    _workspaces = new ObservableCollection<WorkspaceViewModel>();
                    _workspaces.CollectionChanged += OnWorkspacesChanged;
                }
                return _workspaces;
            }
        }

        public override string Error
        {
            get { return ActiveWorkspace != null ? ActiveWorkspace.Error : null; }
        }

        private void OnWorkspacesChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null && e.NewItems.Count != 0)
            {
                foreach (WorkspaceViewModel workspace in e.NewItems)
                {
                    workspace.Closable.RequestClose += OnWorkspaceRequestClose;
                    workspace.PropertyChanged += OnPropertyChanged;
                }
            }


            if (e.OldItems != null && e.OldItems.Count != 0)
            {
                foreach (WorkspaceViewModel workspace in e.OldItems)
                {
                    workspace.Closable.RequestClose -= OnWorkspaceRequestClose;
                    workspace.PropertyChanged -= OnPropertyChanged;
                }
            }
        }

        public event EventHandler<CancelEventArgs> QueryCloseWorkspace;

        private void OnWorkspaceRequestClose(object sender, EventArgs e)
        {
            var workspace = sender as WorkspaceViewModel;
            if (workspace != null)
            {
                var args = new CancelEventArgs(false);
                OnQueryCloseWorkspace(workspace, args);
                if (!args.Cancel)
                    DisposeWorkspace(workspace);
            }
        }

        private void OnQueryCloseWorkspace(WorkspaceViewModel workspace, CancelEventArgs args)
        {
            if (QueryCloseWorkspace != null)
                QueryCloseWorkspace(workspace, args);
        }

        private void DisposeWorkspace(WorkspaceViewModel workspace)
        {
            workspace.Dispose();
            Workspaces.Remove(workspace);
            OnPropertyChanged(() => ActiveWorkspace);
        }

        private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsActive")
            {
                ViewMediator.NotifyColleagues(RequestRepository.REQUEST_ACTIVE_WORKSPACE_CHANGED,
                                              sender.CastTo<WorkspaceViewModel>());
                OnPropertyChanged(() => ActiveWorkspace);
            }
        }

        [MediatorMessageSink(RequestRepository.REQUEST_ERROR_CHANGED, ParameterType = typeof (String))]
        public void ErrorChanged(String errorStr)
        {
            if (errorStr == null) throw new ArgumentNullException("errorStr");
            if (ActiveWorkspace is ContractViewModel)
            {
                OnPropertyChanged(() => Error);
            }
        }

        #endregion // Workspaces

        #region Private Helpers

        public ContractRepositoryViewBasedViewModel ContractRepositoryViewBased
        {
            get
            {
                ContractRepositoryViewBasedViewModel workspace =
                    Workspaces.OfType<ContractRepositoryViewBasedViewModel>().FirstOrDefault();
                if (workspace == null)
                {
                    IContractRepository contractRepository = RepositoryFactory.CreateContractRepository();
                    Contract.Assert(contractRepository != null);
                    workspace = new ContractRepositoryViewBasedViewModel(contractRepository);
                    //workspace.SubContractOpened += new ContractRepositoryViewModel.SubContractEventHandler(workspace_SubContractOpened);
                    AddWorkspace(workspace);
                }
                return workspace;
            }
        }

        private bool CanPrepaymentdocumenttypesShow
        {
            get { return true; }
        }

        private bool CanRolesShow
        {
            get { return true; }
        }

        private bool CanSightfuncpersonschemesShow
        {
            get { return true; }
        }

        private bool CanContractorpropertiesShow
        {
            get { return true; }
        }

        private bool CanAuthoritiesShow
        {
            get { return true; }
        }

        private bool CanTransferacttypedocumentsShow
        {
            get { return true; }
        }

        private bool CanActtypesShow
        {
            get { return true; }
        }

        private bool CanPersonsShow
        {
            get { return true; }
        }

        private bool CanDocumentsShow
        {
            get { return true; }
        }

        private bool CanTransferacttypesShow
        {
            get { return true; }
        }

        private bool CanEmployeesShow
        {
            get { return true; }
        }

        private bool CanDepartmentsShow
        {
            get { return true; }
        }

        private bool CanTroublesShow
        {
            get { return true; }
        }

        private bool CanContractorpositionShow
        {
            get { return true; }
        }

        private bool CanEconomefficiencytypesShow
        {
            get { return true; }
        }

        private bool CanEconomefficiencyparametersShow
        {
            get { return true; }
        }

        private bool CanEfficienceparameterTypesShow
        {
            get { return true; }
        }

        private bool CanCurrencymeasuresShow
        {
            get { return true; }
        }

        private bool CanWorktypesShow
        {
            get { return true; }
        }

        private bool CanFunctionalcustomersShow
        {
            get { return true; }
        }

        private bool CanFunctionalcustomertypesShow
        {
            get { return true; }
        }

        private bool CanTroublesregistresShow
        {
            get { return true; }
        }

        private bool CanPositionsShow
        {
            get { return true; }
        }

        private bool CanPropertiesShow
        {
            get { return true; }
        }

        private bool CanFunccustomerpersonsShow
        {
            get { return true; }
        }

        private bool CanContractortypesShow
        {
            get { return true; }
        }

        private bool CanContractorsShow
        {
            get { return true; }
        }

        private bool CanNtpviewsShow
        {
            get { return true; }
        }

        private bool CanYearreportcolorsShow
        {
            get { return true; }
        }

        private bool CanNtpsubviewsShow
        {
            get { return true; }
        }

        private bool CanNdsesShow
        {
            get { return true; }
        }

        private bool CanRegionsShow
        {
            get { return true; }
        }

        private bool CanNdsalgorithmsShow
        {
            get { return true; }
        }

        private bool CanDegreesShow
        {
            get { return true; }
        }

        private bool CanCurrenciesShow
        {
            get { return true; }
        }

        private bool CanContractTypesShow
        {
            get { return true; }
        }

        private bool CanContractStatesShow
        {
            get { return true; }
        }

        /// <summary>
        /// Получает коллекцию модифицированных рабочих областей
        /// </summary>
        public IEnumerable<WorkspaceViewModel> ModifiedWorkspaces
        {
            get { return Workspaces.Where(x => x.IsModified); }
        }

        public ICommand ShowRelationsEditorCommand
        {
            get { return new RelayCommand(x => OnShowRelationsEditor(), x => ContractSelected); }
        }

        public void ShowContractRepository()
        {
            //var workspace = Workspaces.OfType<ContractRepositoryViewModel>().FirstOrDefault();

            //if (workspace == null)
            //{
            //    var contractRepository = RepositoryFactory.CreateContractRepository();
            //    Contract.Assert(contractRepository != null);
            //    workspace = new ContractRepositoryViewModel(contractRepository);
            //    workspace.SubContractOpened += new ContractRepositoryViewModel.SubContractEventHandler(workspace_SubContractOpened);
            //    AddWorkspace(workspace);
            //}
            SetActiveWorkspace(ContractRepositoryViewBased);
        }


        private void ShowActRepository()
        {
            var workspace = Workspaces.FirstOrDefault(vm => vm is ActRepositoryViewModel) as ActRepositoryViewModel;

            if (workspace == null)
            {
                IContractRepository contractRepository = RepositoryFactory.CreateContractRepository();
                Contract.Assert(contractRepository != null);
                workspace = new ActRepositoryViewModel(contractRepository);
                AddWorkspace(workspace);
            }

            SetActiveWorkspace(workspace);
        }


        private void ShowDisposalsRepository()
        {
            var workspace =
                Workspaces.FirstOrDefault(vm => vm is DisposalsRepositoryViewModel) as DisposalsRepositoryViewModel;

            if (workspace == null)
            {
                IContractRepository contractRepository = RepositoryFactory.CreateContractRepository();
                Contract.Assert(contractRepository != null);
                workspace = new DisposalsRepositoryViewModel(contractRepository);
                AddWorkspace(workspace);
            }

            SetActiveWorkspace(workspace);
        }

        private void ShowOrdersRepository()
        {
            var workspace = Workspaces.FirstOrDefault(vm => vm is OrderRepositoryViewModel) as OrderRepositoryViewModel;

            if (workspace == null)
            {
                IContractRepository contractRepository = RepositoryFactory.CreateContractRepository();
                Contract.Assert(contractRepository != null);
                workspace = new OrderRepositoryViewModel(contractRepository);
                AddWorkspace(workspace);
            }

            SetActiveWorkspace(workspace);
        }


        private void PrepaymentdocumenttypesShow()
        {
            ShowCatalog(CatalogType.Prepaymentdocumenttype);
        }

        private void RolesShow()
        {
            ShowCatalog(CatalogType.Role);
        }

        private void SightfuncpersonschemesShow()
        {
            ShowCatalog(CatalogType.Sightfuncpersonscheme);
        }

        private void ContractorpropertiesShow()
        {
            ShowCatalog(CatalogType.Contractorpropertiy);
        }

        private void AuthoritiesShow()
        {
            ShowCatalog(CatalogType.Authority);
        }

        private void ActtypesShow()
        {
            ShowCatalog(CatalogType.Acttype);
        }

        private void TransferacttypedocumentsShow()
        {
            ShowCatalog(CatalogType.Transferacttypedocument);
        }

        private void PersonsShow()
        {
            ShowCatalog(CatalogType.Person);
        }

        private void DocumentsShow()
        {
            ShowCatalog(CatalogType.Document);
        }

        private void TransferacttypesShow()
        {
            ShowCatalog(CatalogType.Transferacttype);
        }

        private void EmployeesShow()
        {
            ShowCatalog(CatalogType.Employee);
        }

        private void DepartmentsShow()
        {
            ShowHierarchicalCatalog(CatalogType.Department);
        }

        private void TroublesShow()
        {
            ShowHierarchicalCatalog(CatalogType.Trouble);
        }

        private void ContractorpositionShow()
        {
            ShowCatalog(CatalogType.Contractorposition);
        }

        private void EconomefficiencytypesShow()
        {
            ShowCatalog(CatalogType.Economefficiencytype);
        }

        private void EconomefficiencyparametersShow()
        {
            ShowCatalog(CatalogType.Economefficiencyparameter);
        }

        private void EfficienceparameterTypesShow()
        {
            ShowCatalog(CatalogType.Efficienceparametertype);
        }

        private void CurrencymeasuresShow()
        {
            ShowCatalog(CatalogType.Currencymeasure);
        }

        private void WorktypesShow()
        {
            ShowCatalog(CatalogType.Worktype);
        }

        private void FunctionalcustomersShow()
        {
            ShowHierarchicalCatalog(CatalogType.Functionalcustomer);
        }

        private void FunctionalcustomertypesShow()
        {
            ShowCatalog(CatalogType.Functionalcustomertype);
        }

        private void TroublesregistresShow()
        {
            ShowCatalog(CatalogType.Troublesregistry);
        }

        private void PositionsShow()
        {
            ShowCatalog(CatalogType.Position);
        }

        private void PropertiesShow()
        {
            ShowCatalog(CatalogType.Property);
        }

        private void FunccustomerpersonsShow()
        {
            ShowCatalog(CatalogType.Funccustomerperson);
        }

        private void ContractortypesShow()
        {
            ShowCatalog(CatalogType.Contractortype);
        }

        private void ContractorsShow()
        {
            ShowCatalog(CatalogType.Contractor);
        }

        private void NtpviewsShow()
        {
            ShowCatalog(CatalogType.Ntpview);
        }

        private  void YearreportcolorsShow()
        {
            ShowCatalog(CatalogType.Yearreportcolor);
        }

        private void LocationsShow()
        {
            ShowCatalog(CatalogType.Location);
        }

        private void MissiveTypesShow()
        {
            ShowCatalog(CatalogType.MissiveType);
        }

        private void ApprovalGoalsShow()
        {
            ShowCatalog(CatalogType.ApprovalGoal);
        }

        private void ApprovalStatesShow()
        {
            ShowCatalog(CatalogType.ApprovalState);
        }


        private void NtpsubviewsShow()
        {
            ShowCatalog(CatalogType.Ntpsubview);
        }

        private void NdsesShow()
        {
            ShowCatalog(CatalogType.Nds);
        }

        private void RegionsShow()
        {
            ShowCatalog(CatalogType.Region);
        }

        private void SaveLogFile()
        {
            IContractRepository contractRepository = RepositoryFactory.CreateContractRepository();
            var w = new OraExpWindow(contractRepository);
            w.ShowDialog();
        }

        private void NdsalgorithmsShow()
        {
            ShowCatalog(CatalogType.Ndsalgorithm);
        }

        private void DegreesShow()
        {
            ShowCatalog(CatalogType.Degree);
        }

        private void CurrenciesShow()
        {
            ShowCatalog(CatalogType.Currency);
        }

        private void ContractTypesShow()
        {
            ShowCatalog(CatalogType.ContractType);
        }

        private void ContractStatesShow()
        {
            ShowCatalog(CatalogType.ContractState);
        }

        private void ShowCatalog(CatalogType type)
        {
            App.LogMessage("Начало: ShowCatalog()");
            var workspace =
                Workspaces.Where(x => x is CatalogViewModel).FirstOrDefault(x =>
                    {
                        var catalogViewModel = x as CatalogViewModel;
                        return catalogViewModel != null && catalogViewModel.CatalogType == type;
                    }) as CatalogViewModel;

            if (workspace == null)
            {
                IContractRepository contractRepository = RepositoryFactory.CreateContractRepository();
                Contract.Assert(contractRepository != null);
                workspace = new CatalogViewModel(contractRepository)
                    {
                        CatalogType = type
                    };
                AddWorkspace(workspace);
            }

            SetActiveWorkspace(workspace);
            App.LogMessage("Конец: ShowCatalog()");
        }


        private void ShowHierarchicalCatalog(CatalogType type)
        {
            App.LogMessage("Начало: ShowHierarchicalCatalog()");
            var workspace =
                Workspaces.Where(x => x is HierarchicalCatalogViewModel).FirstOrDefault(x =>
                    {
                        var hierarchicalCatalogViewModel = x as HierarchicalCatalogViewModel;
                        return hierarchicalCatalogViewModel != null && hierarchicalCatalogViewModel.CatalogType == type;
                    }) as
                HierarchicalCatalogViewModel;

            if (workspace == null)
            {
                IContractRepository contractRepository = RepositoryFactory.CreateContractRepository();
                Contract.Assert(contractRepository != null);

                workspace = new HierarchicalCatalogViewModel(contractRepository)
                    {
                        CatalogType = type
                    };
                AddWorkspace(workspace);
            }

            SetActiveWorkspace(workspace);
            App.LogMessage("Конец: ShowHierarchicalCatalog()");
        }


        public event EventHandler<ContractArgs> ContractCreateRefused;

        public void OnContractCreateRefused(ContractArgs e)
        {
            EventHandler<ContractArgs> handler = ContractCreateRefused;
            if (handler != null) handler(this, e);
        }

        [MediatorMessageSink(RequestRepository.REQUEST_NEW_CONTRACTDOC, ParameterType = typeof (NewContractdocParams))]
        private void NewContract(NewContractdocParams newContractdocParams)
        {
            Contract.Requires(newContractdocParams != null);
            App.LogMessage("Начало: NewContract()");
            
            ContractViewModel workspace = null;
            
            if (newContractdocParams.Contractdoc != null)
                workspace = FindContractWorkspaceByMainContractdoc(newContractdocParams.Contractdoc.MainContract);

            if (workspace != null)
            {
                if (MessageBox.Show(
                        string.Format("Следует завершить работу с группой договоров {0} перед тем как создавать в ней новый договор.", workspace.Contractdoc.MainContract.Num),
                        "Управление договорами", MessageBoxButton.OK, MessageBoxImage.Warning) == MessageBoxResult.OK)
                {
                    SetActiveWorkspace(workspace);
                    return;
                }
            }

            IContractRepository contractRepository = RepositoryFactory.CreateContractRepository();
            workspace = new ContractViewModel(contractRepository);
            Contractdoc contractdoc = null;

            if (CannotCreateSubreport(newContractdocParams))
            {
                OnContractCreateRefused(new ContractArgs(newContractdocParams.Contractdoc));
                return;
            }

            switch (newContractdocParams.ContractdocType)
            {
                case NewContractdocType.NewGeneral:
                    contractdoc = contractRepository.NewContractdoc();
                    break;
                case NewContractdocType.NewAgreement:
                    Contract.Assert(newContractdocParams.Contractdoc != null);
                    var agreementParams = new NewContractdocParams(newContractdocParams.Contractdoc.Actual,
                                                                   NewContractdocType.NewAgreement);
                    contractdoc = CreateNewAgreementContractdoc(contractRepository, agreementParams);
                    break;
                case NewContractdocType.NewSubgeneral:
                    contractdoc = CreateNewSubgeneralContractdoc(contractRepository, newContractdocParams);
                    break;
            }
            Contract.Assert(contractdoc != null);
            workspace.WrappedDomainObject = contractdoc;
            AddWorkspace(workspace);


            SetActiveWorkspace(workspace);

            //Сохранить договор как только он создан для получения его Id
            //SaveActiveWorkspace();      


            App.LogMessage("Конец: NewContract()");
        }

        private bool CannotCreateSubreport(NewContractdocParams newContractdocParams)
        {
            return SelectedContract != null && !SelectedContract.IsGeneral &&
                   newContractdocParams.ContractdocType == NewContractdocType.NewSubgeneral;
        }

        private Contractdoc CreateNewSubgeneralContractdoc(IContractRepository contractRepository,
                                                           NewContractdocParams newContractdocParams)
        {
            Contractdoc general = contractRepository.GetContractdoc(newContractdocParams.Contractdoc.Id);
            Contract.Assert(general != null);
            contractRepository.DebugPrintRepository();
            Contractdoc contractdoc = contractRepository.NewContractdoc();

            var ch = new Contracthierarchy
                {
                    GeneralContractdoc = general,
                    SubContractdoc = contractdoc
                };

            general.Contracthierarchies.Add(ch);
            contractdoc.Generalcontracthierarchies.Add(ch);

            contractRepository.DebugPrintRepository();
            return contractdoc;
        }

        private Contractdoc CreateNewAgreementContractdoc(IContractRepository contractRepository,
                                                          NewContractdocParams newContractdocParams)
        {
            Contractdoc original = contractRepository.GetContractdoc(newContractdocParams.Contractdoc.Id);
            Contract.Assert(original != null);
            var agreement = (Contractdoc) original.CloneRecursively(null, null);
            original.AddAgreement(agreement);
            return agreement;
        }

        [MediatorMessageSink(RequestRepository.REQUEST_OPEN_CONTRACTDOC, ParameterType = typeof (Contractdoc))]
        private void OpenOriginalContract(Contractdoc selectedContract)
        {
            Contract.Requires(selectedContract != null);
            App.LogMessage("Начало: OpenContract()");
            ContractViewModel workspace = FindContractWorkspace(selectedContract);

            if (workspace == null)
            {
                IContractRepository contractRepository = RepositoryFactory.CreateContractRepository();
                workspace = new ContractViewModel(contractRepository)
                    {WrappedDomainObject = contractRepository.GetContractdoc(selectedContract.Id)};
                Contract.Assume(workspace.WrappedDomainObject != null);
                AddWorkspace(workspace);
            }
            SetActiveWorkspace(workspace);
            App.LogMessage("Конец: OpenContract()");
        }


        private void OpenContract(Contractdoc selectedContract)
        {
            Contract.Requires(selectedContract != null);
            App.LogMessage("Начало: OpenContract()");
            ContractViewModel workspace = FindContractWorkspace(selectedContract);

            if (workspace == null)
                workspace = FindContractWorkspaceByMainContractdoc(selectedContract.MainContract);
            else
            {
                SetActiveWorkspace(workspace);
                return;
            }

            if (workspace == null)
            {
                IContractRepository contractRepository = RepositoryFactory.CreateContractRepository();
                workspace = new ContractViewModel(contractRepository)
                    {WrappedDomainObject = contractRepository.GetContractdoc(selectedContract.Id)};
                Contract.Assume(workspace.WrappedDomainObject != null);
                AddWorkspace(workspace);
                SetActiveWorkspace(workspace);
            }
            else
            {
                if (workspace.IsModified &&
                     MessageBox.Show(
                         string.Format("Группа договоро {0} уже открыта и в ней не завершена работа с договором {1}. Перед открытием договора {2} сохраните изменения в договоре {1}.", workspace.Contractdoc.MainContract.Num, workspace.Contractdoc.Num, selectedContract.Num),
                         "Управление договорами", MessageBoxButton.OK, MessageBoxImage.Warning) == MessageBoxResult.OK)
                {
                    SetActiveWorkspace(workspace);
                }
                else if (!workspace.IsModified)
                {
                    IContractRepository contractRepository = RepositoryFactory.CreateContractRepository();
                    workspace.WrappedDomainObject = contractRepository.GetContractdoc(selectedContract.Id);
                    Contract.Assume(workspace.WrappedDomainObject != null);
                    SetActiveWorkspace(workspace);
                }
            }

            App.LogMessage("Конец: OpenContract()");
        }

        private void AddWorkspace(WorkspaceViewModel workspace)
        {           
            //workspace.MainViewModel = this;

            if (workspace is MainViewModelWorkspace)
                (workspace as MainViewModelWorkspace).MainViewModel = this;
            Workspaces.Add(workspace);

        }

        public event EventHandler<ContractArgs> RequestEditRelation;

        public void OnRequestEditRelation(ContractArgs e)
        {
            EventHandler<ContractArgs> handler = RequestEditRelation;
            if (handler != null) handler(this, e);
        }

        private void OnShowRelationsEditor()
        {
            OnRequestEditRelation(new ContractArgs(SelectedContract));
        }

        

        private ContractViewModel FindContractWorkspace(Contractdoc contractdoc)
        {
            return
                Workspaces.OfType<ContractViewModel>().SingleOrDefault(
                    x =>
                    x.Contractdoc != null && ((x.Contractdoc == contractdoc) || (x.Contractdoc.Id == contractdoc.Id)));
        }

        private ContractViewModel FindContractWorkspaceByMainContractdoc(Contractdoc maincontractdoc)
        {
            return
                Workspaces.OfType<ContractViewModel>().SingleOrDefault(
                    x =>
                    x.Contractdoc != null && ((x.Contractdoc.MainContract == maincontractdoc) || (x.Contractdoc.MainContract.Id == maincontractdoc.Id)));
        }

        public void SetActiveWorkspace(WorkspaceViewModel workspace)
        {
            foreach (WorkspaceViewModel wvm in Workspaces)
            {
                wvm.IsActive = false;
            }
            workspace.IsActive = true;

            OnPropertyChanged(() => ActiveWorkspace);
            OnPropertyChanged(() => Error);
        }

        #endregion // Private Helpers

        public ICommand CloseCommand
        {
            get { return Closable.CloseCommand; }
        }

        private static string FileVersionInfo
        {
            get { return App.FileVersionInfo; }
        }

        private static string AssemblyVersionInfo
        {
            get { return App.AssemblyVersionInfo; }
        }

        private static string ProductInfo
        {
            get { return App.ProductInfo; }
        }

        public bool FastLoad { get; set; }

        #region Fields

        private ObservableCollection<WorkspaceViewModel> _workspaces;

        #endregion // Fields

        public event EventHandler<WrappedObjectCommandArgs<Contractdoc>> NewAgreementCreated;

        public void OnNewAgreementCreated(WrappedObjectCommandArgs<Contractdoc> e)
        {
            EventHandler<WrappedObjectCommandArgs<Contractdoc>> handler = NewAgreementCreated;
            if (handler != null) handler(this, e);
        }

        public event EventHandler<WrappedObjectCommandArgs<Contractdoc>> NewSubgeneralCreated;


        public void OnNewSubgeneralCreated(WrappedObjectCommandArgs<Contractdoc> e)
        {
            EventHandler<WrappedObjectCommandArgs<Contractdoc>> handler = NewSubgeneralCreated;
            if (handler != null) handler(this, e);
        }

        public void SaveWorkspace(WorkspaceViewModel ws)
        {
            Contract.Assert(ws != null);

            try
            {

                ws.SaveCommand.Execute(null);
                ViewMediator.NotifyColleagues(RequestRepository.REQUEST_SAVE_WORKSPACE, ws);

            }

            catch (Exception exception)
            {
                var wrapper = new SaveWorkspaceException("К сожалению произошла ошибка при сохранении ваших результатов работы. Сообщение об ошибке: "
                    + exception.Message, exception);

                // ws.Do(x => x.CollectDiagnosticsData(wrapper));

                throw wrapper;
            }
        }

        private void SaveActiveWorkspace()
        {
            SaveWorkspace(ActiveWorkspace);
        }
    }
}
